#include "kddcup_feat.h"
#include <vector>
#include <algorithm>

using namespace std;

static const int num_items = 6095;
static const int num_users = 2320895;

inline double sqr( double a ){
	return a * a;
}

inline void norm_L2( std::vector<float> &vec ){
    double sum = 0.0;
    for( size_t i = 0; i < vec.size(); i ++ ){
        sum += sqr( vec[i] );
    }
    sum = sqrt( sum );
    double invsum = 1.0 / sum;
    for( size_t i = 0; i < vec.size(); i ++ ){
        vec[i] *= invsum; 
    }		
}

struct CatHist{	
private:
	vector<int> catmap;
    vector<int> catsize;
	vector<int> data;
	vector<int> total;
public:
	CatHist( void ){
	}
	inline void load_catmap( const char *fname ){
		FILE *fi = fopen_check( fname, "r" );
		int iid, cid, cnt = 0;
		while( fscanf( fi, "%d%d%*[^\n]\n", &iid, &cid ) == 2 ){
			assert_true( cnt == iid, "cat map error");
			cnt ++; 
			catmap.push_back( cid );
			while( cid >= (int)catsize.size() ){
                catsize.push_back( 0 );
            }
            catsize[ cid ] ++;
		}
		fclose( fi );
		printf("%d/%d cats loaded\n", num_cat(), cnt );
	}
	inline void init( const char *fsns ){
		data.resize ( num_users * num_cat() );
        total.resize( num_users );
		std::fill( data.begin(), data.end(), 0 );
        std::fill( total.begin(), total.end(), 0 );

		FILE *fi = fopen_check( fsns, "r" );
		int uid, iid;
		while( fscanf( fi, "%d%d%*[^\n]\n", &uid, &iid ) == 2 ){
			assert_true( uid < num_users, "uid assert" );
			if( iid < (int)catmap.size() ){ 
				int cid = catmap[ iid ];
				data[ uid * num_cat() + cid ] ++;
                total[ uid ] ++;
			}
		}
		fclose( fi );		
	}
    
    inline const int* get_hist( int uid )const{
        return &data[ uid * num_cat() ];
    }
	inline int get_histcnt( int uid, int iid ) const{
		assert_true( iid < (int)catmap.size(), "iid exceed bound" );
		int cid = catmap[ iid ];
		return data[ uid * num_cat() + cid ];
	}
    inline int get_catsize( int iid ) const{
		assert_true( iid < (int)catmap.size(), "iid exceed bound" );
		int cid = catmap[ iid ];
        return catsize[ cid ];
    }
    inline int get_total( int uid ) const{
        return total[ uid ];
    }
	inline int num_cat( void ) const{
		return (int)catsize.size();
	}
};

int main(int argc, char* argv[]) {
	if ( argc < 5 ) {
		printf("usage: <cat> <sns> <train> <out>\n");
		return -1;
	}
	
	CatHist hist;
	hist.load_catmap( argv[1] );
	hist.init( argv[2] );
	printf("load history end, start generating...\n");
	FILE *fi = fopen_check( argv[3], "r" );
	FILE *fo = fopen_check( argv[4], "w" );
	fprintf( fo, "1\n" );
	int uid, iid;
	while( fscanf( fi, "%d%d%*[^\n]\n", &uid, &iid ) == 2 ){
        fprintf( fo, "1 0:%d\n", hist.get_histcnt( uid, iid ) );
	}	
	fclose( fi );
	fclose( fo );
	return 0;
}
